//: src/com/silvtar/util/RunCMD.java
/* 
 * Created by 朴晟宁 <piaosn@gmail.com> on 4/21/2013. 
 * Copyright (c) 2013 朴晟宁. All rights reserved.
 * 
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program;
 * 
 * *********************************************************************
 * 
 * Modify History:
 * Date        Version    Description
 * 5/23/2013   0.1        Create the class.
 */

package com.silvtar.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Iterator;
import com.silvtar.io.StdOut;

/**
 * 执行一个命令（调用其他二进制程序）
 * 
 * @author 朴晟宁/Silvtar
 * @author piaosn@gmail.com
 * @version 0.1
 */
public class RunCMD {

    private Runtime           run;        // 与当前 Java 应用程序相关的运行时对象
    private Process           p;          // 命令进程

    private BufferedReader    stdin;

    private BufferedWriter    stdout;

    private BufferedReader    stderr;

    private ArrayList<String> result;     // 命令的控制台输出
    private ArrayList<String> errorResult; // 命令的控制台输出

    /**
     * 调用二进制可执行文件
     * 
     * @param cmd
     *            终端命令
     */
    public RunCMD(String cmd) {

        run = Runtime.getRuntime();

        try {
            // 启动另一个进程来执行命令
            p = run.exec(cmd);
            
            // 检查命令是否执行失败。
            if (p.waitFor() != 0) {
                if (p.exitValue() != 0)// p.exitValue()==0表示正常结束，1：非正常结束
                    StdOut.println(cmd);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 调用二进制可执行文件
     * 
     * @param cmd
     *            终端命令，数组形式
     */
    public RunCMD(String[] cmd) {

        run = Runtime.getRuntime();

        try {
            // 启动另一个进程来执行命令
            p = run.exec(cmd);
            
            // 检查命令是否执行失败。
            if (p.waitFor() != 0) {
                if (p.exitValue() == 1)// p.exitValue()==0表示正常结束，1：非正常结束
                    StdOut.println(cmd[0]);
                StdOut.printErr("失败!");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得命令的输出信息
     * 
     * @return 每行的信息
     */
    public ArrayList<String> getResult() {
        if (result == null) {
            result = new ArrayList<String>();
            try {
                String lineStr;
                if (getStdIn().ready()) {
                    while ((lineStr = getStdIn().readLine()) != null) {
                        result.add(lineStr);
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    public ArrayList<String> getErrorResult() {
        if (errorResult == null) {
            errorResult = new ArrayList<String>();
            try {
                String lineStr;
                if (getStdErr().ready()) {
                    while ((lineStr = getStdErr().readLine()) != null) {
                        result.add(lineStr);
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 打印命令输出结果
     */
    public void printResult() {
        getResult();
        for (Iterator<String> iterator = result.iterator(); iterator.hasNext();) {
            String string = iterator.next();
            StdOut.println(string);
        }
    }

    public void printErrResult() {
        getErrorResult();
        for (Iterator<String> iterator = errorResult.iterator(); iterator
                .hasNext();) {
            String string = iterator.next();
            StdOut.println(string);
        }
    }

    public BufferedReader getStdIn() {
        if (stdin == null) {
            stdin = new BufferedReader(new InputStreamReader(
                    new BufferedInputStream(p.getInputStream())));
        }
        return stdin;
    }

    public BufferedWriter getStdOut() {
        if (stdout == null) {
            stdout = new BufferedWriter(new OutputStreamWriter(
                    p.getOutputStream()));
        }
        return stdout;
    }

    public BufferedReader getStdErr() {
        if (stderr == null) {
            stderr = new BufferedReader(new InputStreamReader(
                    p.getErrorStream()));
        }
        return stderr;
    }

    public void send(String cmd) {
        getStdOut();
        try {
            stdout.write(cmd);
            stdout.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试用例
     */
    static public void test() {
        RunCMD runCMD = new RunCMD("ls");
        runCMD.printResult();

    }
}
